; 16 bit division and modulo functions
; for both signed and unsigned values
;
#include once <neg16.asm>
;
__DIVU16:    ; 16 bit unsigned division
; HL = Dividend, Stack Top = Divisor
;   -- OBSOLETE ; Now uses FASTCALL convention
;   ex de, hl
;	pop hl      ; Return address
;	ex (sp), hl ; CALLEE Convention

__DIVU16_FAST:
lda z80_h           ;- ld a,h
sta z80_a
lda z80_l           ;- ld c,l
sta z80_c
lda #0              ;- ld hl,0
sta z80_l
lda #0
sta z80_h
lda #16             ;- ld b,16
sta z80_b

__DIV16LOOP:
                    ;- sll c
                    ;- rla
lda z80_l           ;- adc hl,hl
adc z80_l
sta z80_l
lda z80_h
adc z80_h
sta z80_h
                    ;- sbc hl,de
jcs __DIV16NOADD    ;- jr nc, __DIV16NOADD
clc                 ;- add hl,de
lda z80_l
adc z80_e
sta z80_l
lda z80_h
adc z80_d
sta z80_h
dec z80_c           ;- dec c

__DIV16NOADD:
                    ;- djnz __DIV16LOOP
lda z80_e            ;- ex de,hl
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
lda z80_a           ;- ld h,a
sta z80_h
lda z80_c           ;- ld l,c
sta z80_l
rts                 ;- ret     ; HL = quotient, DE = Mudulus

__MODU16:    ; 16 bit modulus
; HL = Dividend, Stack Top = Divisor
;ex de, hl
;pop hl
;ex (sp), hl ; CALLEE Convention
jsr __DIVU16_FAST   ;- call __DIVU16_FAST
lda z80_e           ;- ex de, hl	; hl = reminder (modulus)
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
; de = quotient
rts                 ;- ret

__DIVI16:	; 16 bit signed division
;	--- The following is OBSOLETE ---
;	ex de, hl
;	pop hl
;	ex (sp), hl 	; CALLEE Convention

__DIVI16_FAST:
lda z80_d           ;- ld a,d
sta z80_a
eor z80_h           ;- xor h
ldx z80_ap          ;- ex af,af'		; BIT 7 of a contains result
sta z80_ap
txa
lda z80_d           ;- bit 7,d		; DE is negative?
bit 7
jeq __DIVI16A       ;- jr z, __DIVI16A
lda z80_e           ;- ld a,e			; DE = -DE
sta z80_a
eor #$ff            ;- cpl
lda z80_a           ;- ld e,a
sta z80_e
lda z80_d           ;- ld a,d
sta z80_a
eor #$ff            ;- cpl
lda z80_a           ;- ld d,a
sta z80_d
inc z80_e           ;- inc de
bne *+4
inc z80_d

__DIVI16A:
lda z80_h           ;- bit 7,h		; HL is negative?
bit 7
beq *+5             ;- call nz, __NEGHL
jsr __NEGHL

__DIVI16B:
jsr __DIVU16_FAST   ;- call __DIVU16_FAST
ldx z80_ap          ;- ex af,af'
sta z80_ap
txa
ora z80_a           ;- or a
bmi *+3             ;- ret p	; return if positive
rts
jmp __NEGHL         ;- jp __NEGHL

__MODI16:    ; 16 bit modulus
; HL = Dividend, Stack Top = Divisor
;ex de, hl
;pop hl
;ex (sp), hl ; CALLEE Convention
jsr __DIVI16_FAST   ;- call __DIVI16_FAST
lda z80_e           ;- ex de,hl	; hl = reminder (modulus)
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
; de = quotient
rts                 ;- ret

